import express, { Application, NextFunction, Request, Response } from 'express';
import helmet from 'helmet';
import morgan from 'morgan';
import routes from './routes';
import logger from './utils/logger';
import { globalRateLimit } from './middleware/rateLimit';
import { corsMiddleware, devCorsMiddleware, validateCorsConfig, getCorsInfo } from './middleware/cors';
import dotenv from 'dotenv';
import path from 'path';
import errorHandler from './middleware/errorHandler';
import { ResponseUtil } from './utils/R';


const app: Application = express();


dotenv.config({
    path: path.resolve(process.cwd(), '.env')
});

const nodeEnv = process.env.NODE_ENV || 'development';
const envFile = nodeEnv === 'production' ? '.env.pro' : '.env.dev';

dotenv.config({
    path: path.resolve(process.cwd(), envFile),
    override: true
});

// 中间件配置
app.use(helmet({
    contentSecurityPolicy: {
        directives: {
            defaultSrc: ["'self'"],
            styleSrc: ["'self'", "'unsafe-inline'"],
            scriptSrc: ["'self'"],
            imgSrc: ["'self'", "data:", "https:"],
        },
    },
}));

// 验证和应用CORS配置
validateCorsConfig();

// 根据环境选择CORS中间件
if (process.env.NODE_ENV === 'development') {
    app.use(devCorsMiddleware);
    logger.info('✅ 开发环境CORS中间件已启用（宽松模式）');
} else {
    app.use(corsMiddleware);
    logger.info('✅ 生产环境CORS中间件已启用（严格模式）');
}


// 跨域支持
app.use(express.json({ limit: '10mb' })); // JSON解析
app.use(express.urlencoded({ extended: true, limit: '10mb' })); // URL编码解析

// 提供静态文件服务
app.use('/public', express.static(path.join(__dirname, '../public')));

// 创建Morgan中间件，将HTTP请求日志集成到Winston
const morganMiddleware = morgan(
    // 定义日志格式：方法 URL 状态码 响应大小 - 响应时间
    ':method :url :status :res[content-length] - :response-time ms',
    {
        // 将Morgan的输出流连接到Winston
        stream: {
            write: (message: string) => {
                // 使用http级别记录请求日志，去除末尾换行符
                logger.http(message.trim());
            },
        },
    }
);

app.use(morganMiddleware);

// 全局限流中间件
app.use(globalRateLimit);

// 根路由
app.get('/', (req: Request, res: Response) => {
    res.json({
        message: `欢迎使用${process.env.PROJECT_NAME}后端服务器！`,
        timestamp: new Date().toISOString(),
        version: '1.0.0'
    });
});

// API路由
// app.use('/api/auth', authRoutes);
routes.map(route => {
    app.use('/api' + route.path, route.router);
});


// CORS配置信息路由
app.get('/cors-info', (req: Request, res: Response) => {
    const corsInfo = getCorsInfo();
    res.json({
        success: true,
        data: {
            ...corsInfo,
            environment: process.env.NODE_ENV || 'development',
            timestamp: new Date().toISOString()
        }
    });
});

// 健康检查路由
app.get('/health', async (req: Request, res: Response) => {
    try {
        console.log("req",req.headers);
        
        const { db } = await import('./config/database');

        // 获取数据库健康状态
        const dbHealth = await db.healthCheck();
        const dbStatus = db.status();

        const healthData = {
            status: 'ok',
            timestamp: new Date().toISOString(),
            uptime: process.uptime(),
            database: {
                mysql: {
                    connected: dbHealth.mysql,
                    status: dbStatus.mysql.status
                },
                redis: {
                    connected: dbHealth.redis,
                    status: dbStatus.redis.status
                }
            },
            memory: process.memoryUsage(),
            env: process.env.NODE_ENV
        };

        // 如果任何数据库连接失败，返回503状态
        const allHealthy = dbHealth.mysql && dbHealth.redis;

        res.status(allHealthy ? 200 : 503).json(healthData);
    } catch (error) {
        res.status(500).json({
            status: 'error',
            timestamp: new Date().toISOString(),
            error: 'Health check failed'
        });
    }
});

// 在所有路由之后添加404处理中间件
app.use((req: Request, res: Response, next: NextFunction) => ResponseUtil.notFound(res, `路由 ${req.originalUrl} 不存在`));

// 500错误处理 - 必须在最后
app.use(errorHandler);

// 错误处理中间件
app.use((error: any, req: Request, res: Response, next: any) => {
    console.error('服务器错误:', error);
    res.status(500).json({
        error: '内部服务器错误',
        message: process.env.NODE_ENV === 'development' ? error.message : '服务器遇到错误'
    });
});

export default app; 